package cn.openea.perpartner.system.util;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import cn.openea.perpartner.common.core.constant.UserConstants;
import cn.openea.perpartner.common.core.utils.IdUtil;
import cn.openea.perpartner.common.core.utils.IdWorker;
import cn.openea.perpartner.system.service.ISysUserService;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * @codeDesc:公共组件函数
 * @author: Mr.Yun
 * @QQ: 2034374624
 * @version: V1.0
 * @Created: 2021/08/18 17:10
 */
@Component
public class ToolsUtil implements ApplicationContextAware {
    private static ApplicationContext applicationContext;
    private static IdWorker worker = new IdWorker(1, 1, 1);

    /**
     * 获取用户ID身份
     * 格式：yyMMddhhmmssSSS+3位随机数
     *
     * @return 返回用户身份id，保证id唯一
     */
    public static String autoUserID() {
        return autoUserID(true, 3);
    }

    /**
     * 获取用户ID身份
     * 格式：yyMMddhhmmssSSS+randomSize位随机数
     *
     * @param forceCheck 是否强制验证用户ID唯一
     * @param randomSize 定制id后随机的数字个数
     * @return 返回获取的身份ID
     */
    public static String autoUserID(boolean forceCheck, int randomSize) {
        String sformat = "yyMMddhhmmssSSS";
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat(sformat);
        String dateString = formatter.format(currentTime);
        String numStr = "";
        for (int i = 0; i < randomSize; i++) {
            numStr += (int) (10 * (Math.random()));
        }
        String thisUserid = dateString + numStr;
        if (forceCheck) {
            ISysUserService userService = ToolsUtil.getBean(ISysUserService.class);
            if (UserConstants.NOT_UNIQUE.equals(userService.checkUserUnique(thisUserid))) {
                thisUserid = autoUserID(forceCheck, randomSize);
            }
        }
        return thisUserid;
    }
    public static String autoUserID(int randomSize) {
        String sformat = "yyyyMMddhhmmssSSS";
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat(sformat);
        String dateString = formatter.format(currentTime);
        String numStr = "";
        for (int i = 0; i < randomSize; i++) {
            numStr += (int) (10 * (Math.random()));
        }
        String thisUserid = dateString + numStr;
        return thisUserid;
    }

    /**
     * 获取用户ID身份
     * 格式：yyMMddhhmmssSSS+randomSize位随机数
     *
     * @param randomSize 定制id后随机的数字个数
     * @return 返回获取的身份ID
     */
    public static String autoUserID(String beginDate, String endDate, int randomSize) {
        String sformat = "yyMMddhhmmssSSS";
        Date currentTime = randomDate(beginDate, endDate);
        SimpleDateFormat formatter = new SimpleDateFormat(sformat);
        String dateString = formatter.format(currentTime);
        String numStr = "";
        for (int i = 0; i < randomSize; i++) {
            numStr += (int) (10 * (Math.random()));
        }
        String thisUserid = dateString + numStr;
        ISysUserService userService = ToolsUtil.getBean(ISysUserService.class);
        if (UserConstants.NOT_UNIQUE.equals(userService.checkUserUnique(thisUserid))) {
            thisUserid = autoUserID(true, randomSize);
        }
        return thisUserid;
    }

    /**
     * 获取随机日期
     */
    private static Date randomDate(String beginDate, String endDate) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date startDate = sdf.parse(beginDate);
            Date endedDate = sdf.parse(endDate);
            long start = startDate.getTime();
            long end = endedDate.getTime();
            Random random = new Random();
            long randomDate = start + (long) (random.nextFloat() * (end - start + 1));
            return new Date(randomDate);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 获取唯一ID，重复概率极小，16位长度的long
     *  累积32台机器，每秒可以生成65万个不重复序列号
     *  ID具有渐大（类自增）且具有排序性，基于Snowflake算法进行改造升级
     * @return 唯一ID
     */
    public static long getUniqueID() {
        return IdUtil.nextId();
    }
    /**
     * 获取唯一ID，重复概率极极极小，19位长度的long，19位长度的long
     * 本机机器id=1
     * ID具有渐大（类自增）且具有排序性，基于Snowflake算法进行生成
     *
     * @return
     */
    public static long getNewUnid() {
        return worker.nextId();
    }

    /**
     * 过滤昵称中的表情
     */
    public static String filterEmoji(String nickName) {
        //nick_name 所获取的用户昵称
        if (nickName == null) {
            return nickName;
        }
        String patternStr = "[^\\u0000-\\uFFFF]";
        Pattern emoji = Pattern.compile(patternStr, Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE);
        Matcher emojiMatcher = emoji.matcher(nickName);
        if (emojiMatcher.find()) {
            //将所获取的表情转换为*
            nickName = emojiMatcher.replaceAll("*");
            return nickName;
        }
        return nickName;
    }

    /**
     * 获取用户私密信息
     */
    public static JSONObject getData(String code, String appid, String secret) {
        if (StrUtil.isNotBlank(code)) {
            String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appid + "&secret=" + secret + "&js_code=" + code + "&grant_type=authorization_code";
            String wxResult = HttpUtil.get(url);
            return JSONObject.parseObject(wxResult);
        }
        return null;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (ToolsUtil.applicationContext == null) {
            ToolsUtil.applicationContext = applicationContext;
        }
    }

    /**
     * 获取applicationContext
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }



    /**
     * 通过class获取Bean.
     *
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }


}
